﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICMS.PluginInterfaces;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using SharpCompress.Archive;
using SharpCompress.Common;
using SharpCompress.Reader;
using commonImportPlugin.Factorys;
using commonImportPlugin.FilesCore;
using commonImportPlugin.Config;
using commonImportPlugin.Common;
using System.Reflection;
using commonImportPlugin.FilesCore.MedicalFile;
using commonImportPlugin.Configs.Base;
using commonImportPlugin.Decrypt;
using commonImportPlugin.Configs.Other;
using commonImportPlugin.Config.Else;

namespace ICMS2.XXXXXXXYHImportDriver100
{
    /// <summary>
    ///XXXXXXX银行数据导入插件（每一家银行对应一配置文件）
    /// 开发：林泽填
    /// 版本：V1.0.0.151211
    /// 升级记录：首次发布
    /// 1.本插件解析处理社保数据，磁条，金融数据。
    /// 2.导入数据时，若数据用多层压缩包打包，本插件自动解压获取数据，导入结束会自动清理解压产生的文件。
    /// 3.若选择非文件夹导入方式，所选择的文件不可是文件夹
    /// </summary>
    class ICMS2XXXXXXXYHImportPlugin100 : IImportPlugin
    {
        #region 基本配置变量

        //ICData最终结果
        public ICData[] ResultICRecords { get; private set; }

        //基本的配置信息类
        private IAppConfig _config;
        //二进制辅助工具
        private IBinaryHelper _helper;
        //金融加密机实例
        private IHSM[] _pbocHSMs;
        //项目ID
        private string _projectID;
        //社保加密机实例
        private IHSM[] _ssHSMs;
        //工单号
        private string _taskID;
        //来自网站的配置信息
        private string _configText;

        private bool _importFlag;

        public Context context = null;


        private int _dataCounts;    //总数据量

        //匹配记录
        private int _currentRecord;

        private StringBuilder _sbMatchLog;

        int sortId = 1;
        #endregion

        #region 公共变量
        //制卡文件处理核心库
        AllCores allCores = null;//所有核心工厂类

        //其他
        CommonUtil commonUtil = CommonUtil.GetInstance();//公共类处理核心
        GetFileUtil getFileUtil = new GetFileUtil();//获取文件辅助类

        //制卡文件集
        AllFiles allFiles = null;//所有制卡数据
        List<string> needRemoveDataFiles = new List<string>();//解压产生的垃圾文件

        //最终数据集
        Queue<ICData> finalIcDatas = new Queue<ICData>();

        //基本配置
        InitConfig initConfig = null;

        //其他
        bool isFirst = true;//是否第一次导
        #endregion

        #region 版本信息
        public string Description
        {
            get { return "XXXXXXX银行数据导入插件"; }
        }
        public string Name
        {
            get { return "XXXXXXX银行数据导入插件_V1.0.0.160112"; }
        }

        public string Version
        {
            get { return "V1.0.0.160112"; }
        }
        #endregion

        #region IAppModule 成员
        public string Memo { get; private set; }

        public int Progress { get; private set; }

        public int PBOCHSMCount
        {
            get { return 1; }
        }

        public int SSHSMCount
        {
            get { return 1; }
        }
        public string SetupConfig(bool edit, IAppConfig config)
        {
            this._config = config;
            this._helper = this._config.BinaryHelper;
            this._pbocHSMs = this._config.POBCHSMs;
            this._ssHSMs = this._config.SSHSMs;
            this._projectID = this._config.ProjectID;
            this._taskID = this._config.TaskID;
            this._configText = this._config.ConfigText;

            /////////初始化上下文///////////
            context = new Context();
            context.pbocHSMs = this._config.POBCHSMs;
            context.projectId = this._config.ProjectID;
            context.taskId = this._config.TaskID;
            context.hsmBankId = "6228230675017075864";
            context.succeedLogFilePth = string.Format(@"{0}\导入成功的日志\{1}_{2}.txt", Application.StartupPath, context.projectId, context.taskId);
            context.Init(context);
            return null;
        }

        public bool ConfirmResult()
        {
            if (this._sbMatchLog.ToString().Length != 0)
            {
                var chk = MessageBox.Show("导入已经结束，插件返回信息:" + this._sbMatchLog.ToString(), "确认导入结果", MessageBoxButtons.YesNo)
                    == System.Windows.Forms.DialogResult.Yes;
                if (!chk)
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 成功导入成功的日志
        /// </summary>
        private void createLog(List<ICData> icResult)
        {
            InitConfig initConfig = InitConfig.GetConfig();

            if (string.IsNullOrEmpty(initConfig.createLogItems))
                return;
            commonUtil.CreateSucceedLogFile(initConfig.createLogItems, icResult, context.succeedLogFilePth);//生成日志
        }
        #endregion

        #region 导入init与Import 核心函数

        /// <summary>
        /// 导入核心函数
        /// </summary>
        /// <returns></returns>
        public int Import()
        {
            if (isFirst)
            {
                //获取金融，磁条，社保，医保，匹配数据文件
                #region

                //初始化变量
                string empleyError = "（原因：1,制卡数据为空,2,当前导入的数据是之前成功导入过的数据 3，配置有误）";
                Dictionary<string, List<ICData>> allMatchDatas = new Dictionary<string, List<ICData>>();//存放数据的Dictionary
                List<ICData> pbocDatas = null;//原始金融数据
                List<ICData> ssseDatas = null;//原始社保数据
                List<ICData> trackDatas = null;//原始磁条数据
                List<MedicalData> medicalDatas = null;//原始医保数据
                List<ICData> matchDatas = null;//原始匹配数据

                int pbocCount = 0;
                int ssseCount = 0;
                int trackCount = 0;
                int medicalCount = 0;
                int matchCount = 0;

                //获取金融数据
                if (allCores.pbocFileCore != null)
                {
                    pbocDatas = new List<ICData>();
                    pbocDatas = allCores.pbocFileCore.GetPbocAllDatas(allFiles.pbocFiles, out pbocCount);
                    if (pbocDatas== null || pbocDatas.Count == 0)
                        throw new Exception("金融数据为空!" + empleyError);
                    allMatchDatas.Add("pboc", pbocDatas);
                    this.Memo = this.Memo.Replace("金融:-1", pbocCount.ToString());
                }

                //获取社保数据
                if (allCores.ssseFileCore != null)
                {
                    ssseDatas = new List<ICData>();
                    ssseDatas = allCores.ssseFileCore.GetSsseAllDatas(allFiles.ssseFiles[0], out ssseCount);
                    if (ssseDatas==null || ssseDatas.Count == 0)
                        throw new Exception("社保数据为空!" + empleyError);

                    allMatchDatas.Add("ssse", ssseDatas);
                    this.Memo = this.Memo.Replace("社保:-1", ssseCount.ToString());
                }

                //获取磁条数据
                if (allCores.trackFileCore != null)
                {
                    trackDatas = new List<ICData>();
                    trackDatas = allCores.trackFileCore.GetTrackAllDatas(allFiles.trackFiles, out trackCount);
                    if (trackDatas == null || trackDatas.Count == 0)
                        throw new Exception("磁条数据为空!" + empleyError);
                    allMatchDatas.Add("track", trackDatas);
                    this.Memo = this.Memo.Replace("磁条:-1", trackCount.ToString());
                }

                //获取医保数据
                if (allCores.medicalFileCore != null)
                {
                    medicalDatas = new List<MedicalData>();
                    medicalDatas = allCores.medicalFileCore.GetMedicalAllDatas(allFiles.medicalFiles, out medicalCount);
                    if (medicalDatas== null || medicalDatas.Count == 0)
                        throw new Exception("医保数据为空!" + empleyError);
                    this.Memo = this.Memo.Replace("医保:-1", medicalCount.ToString());
                }

                //获取匹配数据
                if (allCores.matchFileCore != null)
                {
                    matchDatas = new List<ICData>();
                    matchDatas = allCores.matchFileCore.GetMatchAllDatas(allFiles.matchFiles, out matchCount);
                    if (matchDatas == null || matchDatas.Count == 0)
                        throw new Exception("匹配数据为空!" + empleyError);
                    allMatchDatas.Add("match", matchDatas);
                    this.Memo = this.Memo.Replace("匹配:-1", matchCount.ToString());
                }
                #endregion

                //对以上提取的数据做匹配
                #region
                List<ICData> finalDatas = new List<ICData>();//存放最终匹配结果的值  

                if (allMatchDatas.Count > 1)
                {   //两种数据格式以上情况
                    if (allCores.matchCore == null)
                        throw new Exception("当数据种类2种（含2种）以上，需配置匹配参数！请配置");
                    finalDatas = allCores.matchCore.CommonMatch<Dictionary<string, List<ICData>>, List<MedicalData>>(allMatchDatas, medicalDatas, this._taskID);
                }
                else
                {   //一种数据格式情况
                    foreach (string key in allMatchDatas.Keys)
                        finalDatas = allMatchDatas[key];
                }

                #endregion

                //解密数据(针对个别需要解密数据的项目)
                #region

                if (!string.IsNullOrEmpty(initConfig.decryptMode))
                {
                    CommonDecryptClass decryptClass = new CommonDecryptClass();
                    finalDatas = decryptClass.commonDecrypt(finalDatas, initConfig.decryptMode, context);

                    //起始sortId
                    sortId = commonUtil.ReadSortIdValue(context.succeedLogFilePth);
                }
                #endregion

                //将数据压入队列
                #region

                foreach (ICData data in finalDatas)
                    finalIcDatas.Enqueue(data);
                this._dataCounts = finalIcDatas.Count;
                #endregion

                isFirst = false;
            }

            //循环导入数据，每次最多导入1000条
            #region

            List<ICData> icResult = new List<ICData> { };//数据列表

            //分多次导入控制
            #region
            while (icResult.Count < 1000)
            {
                ICData icData = new ICData();
                if (finalIcDatas.Count != 0)//未完成
                {
                    icData = this.finalIcDatas.Dequeue();
                    icData.SortID = sortId++;
                    icResult.Add(icData);
                }
                else//已完成
                {
                    this.Progress = 100;
                    break;
                }

                //如果全部匹配完成
                if (this._currentRecord + icResult.Count == this._dataCounts)
                {
                    this.Progress = 100;
                    break;
                }
            }
            #endregion

            //未完毕则记录已导入数
            #region
            if (this.Progress != 100)
            {
                this._currentRecord += icResult.Count;
                this.Progress = (this._currentRecord * 100) / this._dataCounts;
            }
            #endregion

            //最终存放结果
            createLog(icResult);//生成成功的日志
            ResultICRecords = icResult.ToArray();//最终结果
            #endregion

            //垃圾回收（针对输入是压缩包的项目)
            #region
            foreach (string foler in needRemoveDataFiles)
            {
                if (Directory.Exists(foler))
                    Directory.Delete(foler, true);
            }
            #endregion

            return icResult.Count;
        }

        /// <summary>
        /// 导入初始化函数
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="filePaths"></param>
        /// <returns></returns>
        public int Init(string folder, string[] filePaths)
        {
            //初始化变量
            this._sbMatchLog = new StringBuilder();
            this._importFlag = false;
            this._currentRecord = 0;
            string configs = this._configText;
            List<string> allDataFiles = new List<string>();
            PligunUtil pligunUtil = new PligunUtil();

            //初始化配置
            ConfigCore configCore = new ConfigCore();//初始配置
            initConfig = InitConfig.GetConfig();//初始化配置

            //初始化核心函数
            allCores = pligunUtil.InitCores(configCore.GetAllFactoryNames());

            //获取数据文件
            Dictionary<string, string> dicFileFilterRules = null;
            string strFileExtensions = configCore.GetAllFileExtendsion(out dicFileFilterRules);//获取所有文件扩展名正则

            getFileUtil.GetAllDataFiles(folder, filePaths, strFileExtensions,//获取所有文件
                out allDataFiles, out needRemoveDataFiles);

            if (allDataFiles.Count == 0)
                throw new Exception("获取数据文件为空，请检查配置！");

            //获取数据文件数量及文件集
            string commentMessage = "";//提示条数信息
            Dictionary<string, int> coutsMessage = new Dictionary<string, int>();//各制卡数据记录数情况

            this._dataCounts = pligunUtil.InitFilesAndGetCount(allCores, configCore, allDataFiles, dicFileFilterRules,
                out commentMessage, out allFiles, out coutsMessage);//获取数据文件及数量

            //判断数量是否一致
            pligunUtil.CountCheck(coutsMessage);

            this.Memo = commentMessage;

            return this._dataCounts;
        }
        #endregion
    }
}
